home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2002 November / CD 1 / APC0211D1.ISO / workshop / prog / files / ActivePerl-5.6.1.633-MSWin32.msi / _b6adf8023f85b0a7f12e7120cda7402d < prev    next >
Encoding:
Text File  |  2001-11-21  |  54.6 KB  |  1,919 lines

  1. package XML::Simple;
  2.  
  3. =head1 NAME
  4.  
  5. XML::Simple - Easy API to read/write XML (esp config files)
  6.  
  7. =head1 SYNOPSIS
  8.  
  9.     use XML::Simple;
  10.  
  11.     my $ref = XMLin([<xml file or string>] [, <options>]);
  12.  
  13.     my $xml = XMLout($hashref [, <options>]);
  14.  
  15. Or the object oriented way:
  16.  
  17.     require XML::Simple;
  18.  
  19.     my $xs = new XML::Simple(options);
  20.  
  21.     my $ref = $xs->XMLin([<xml file or string>] [, <options>]);
  22.  
  23.     my $xml = $xs->XMLout($hashref [, <options>]);
  24.  
  25. =cut
  26.  
  27. # See after __END__ for more POD documentation
  28.  
  29.  
  30. # Load essentials here, other modules loaded on demand later
  31.  
  32. use strict;
  33. use Carp;
  34. require Exporter;
  35.  
  36.  
  37. ##############################################################################
  38. # Define some constants
  39. #
  40.  
  41. use vars qw($VERSION @ISA @EXPORT);
  42.  
  43. @ISA               = qw(Exporter);
  44. @EXPORT            = qw(XMLin XMLout);
  45. $VERSION           = '1.06';
  46.  
  47. my %CacheScheme    = (
  48.                        storable => [ \&StorableSave, \&StorableRestore ],
  49.                        memshare => [ \&MemShareSave, \&MemShareRestore ],
  50.                        memcopy  => [ \&MemCopySave,  \&MemCopyRestore  ]
  51.              );
  52.  
  53. my $DefaultValues  = 1;       # Used for locking only
  54. my @KnownOptIn     = qw(keyattr keeproot forcecontent contentkey noattr
  55.                         searchpath forcearray cache suppressempty parseropts);
  56. my @KnownOptOut    = qw(keyattr keeproot contentkey noattr
  57.                         rootname xmldecl outputfile noescape suppressempty);
  58. my @DefKeyAttr     = qw(name key id);
  59. my $DefRootName    = qq(opt);
  60. my $DefContentKey  = qq(content);
  61. my $DefXmlDecl     = qq(<?xml version='1.0' standalone='yes'?>);
  62.  
  63.  
  64. ##############################################################################
  65. # Globals for use by caching routines (access protected by locks)
  66. #
  67.  
  68. my %MemShareCache  = ();
  69. my %MemCopyCache   = ();
  70.  
  71.  
  72. ##############################################################################
  73. # Dummy 'lock' routine for non-threaded versions of Perl
  74. #
  75.  
  76. BEGIN {
  77.   if($] < 5.005) {
  78.     eval "sub lock {}";
  79.   }
  80. }
  81.  
  82.  
  83. ##############################################################################
  84. # Constructor for optional object interface.
  85. #
  86.  
  87. sub new {
  88.   my $class = ref($_[0]) || $_[0];      # Works as object or class method
  89.   shift;
  90.  
  91.   if(@_ % 2) {
  92.     croak "Default options must be name=>value pairs (odd number supplied)";
  93.   }
  94.  
  95.   my $self = { defopt => { @_ } };
  96.  
  97.   return(bless($self, $class));
  98. }
  99.  
  100.  
  101. ##############################################################################
  102. # Sub/Method: XMLin()
  103. #
  104. # Exported routine for slurping XML into a hashref - see pod for info.
  105. #
  106. # May be called as object method or as a plain function.
  107. #
  108. # Expects one arg for the source XML, optionally followed by a number of
  109. # name => value option pairs.
  110. #
  111.  
  112. sub XMLin {
  113.  
  114.   # If this is not a method call, create an object
  115.  
  116.   my $self;
  117.   if($_[0]  and  UNIVERSAL::isa($_[0], 'XML::Simple')) {
  118.     $self = shift;
  119.   }
  120.   else {
  121.     $self = new XML::Simple();
  122.   }
  123.  
  124.  
  125.   my $string = shift;
  126.  
  127.   $self->handle_options('in', @_);
  128.  
  129.  
  130.   # If no XML or filename supplied, look for scriptname.xml in script directory
  131.  
  132.   unless(defined($string))  {
  133.     
  134.     # Translate scriptname[.suffix] to scriptname.xml
  135.  
  136.     require File::Basename;
  137.  
  138.     my($ScriptName, $ScriptDir, $Extension) =
  139.       File::Basename::fileparse($0, '\.[^\.]+');
  140.  
  141.     $string = $ScriptName . '.xml';
  142.  
  143.  
  144.     # Add script directory to searchpath
  145.     
  146.     if($ScriptDir) {
  147.       unshift(@{$self->{opt}->{searchpath}}, $ScriptDir);
  148.     }
  149.   }
  150.   
  151.  
  152.   # Are we parsing from a file?  If so, is there a valid cache available?
  153.  
  154.   my($filename, $scheme);
  155.   unless($string =~ m{<.*?>}s  or  ref($string)  or  $string eq '-') {
  156.  
  157.     require File::Basename;
  158.     require File::Spec;
  159.  
  160.     $filename = $self->find_xml_file($string, @{$self->{opt}->{searchpath}});
  161.  
  162.     if($self->{opt}->{cache}) {
  163.       lock(%CacheScheme);
  164.       foreach $scheme (@{$self->{opt}->{cache}}) {
  165.     croak "Unsupported caching scheme: $scheme"
  166.       unless($CacheScheme{$scheme});
  167.  
  168.     my $opt = $CacheScheme{$scheme}->[1]->($filename);
  169.     return($opt) if($opt);
  170.       }
  171.     }
  172.   }
  173.   else {
  174.     delete($self->{opt}->{cache});
  175.     if($string eq '-') {
  176.       # Read from standard input
  177.       $filename = '-';
  178.     }
  179.   }
  180.  
  181.  
  182.   # Parsing is required, so let's get on with it
  183.  
  184.   my $tree =  $self->build_tree($filename, $string);
  185.  
  186.  
  187.   # Now work some magic on the resulting parse tree
  188.  
  189.   my($ref);
  190.   if($self->{opt}->{keeproot}) {
  191.     $ref = $self->collapse({}, @$tree);
  192.   }
  193.   else {
  194.     $ref = $self->collapse(@{$tree->[1]});
  195.   }
  196.  
  197.   if($self->{opt}->{cache}) {
  198.     $CacheScheme{$self->{opt}->{cache}->[0]}->[0]->($ref, $filename);
  199.   }
  200.  
  201.   return($ref);
  202. }
  203.  
  204.  
  205. ##############################################################################
  206. # Method: build_tree()
  207. #
  208. # If parsing is required, this is the routine that does it - using the 'Tree'
  209. # style of XML::Parser.
  210. #
  211. # If you're planning to override this routine, your version should return the
  212. # same type of data structure as an XML::Parser Tree (summarised in the 
  213. # comments for the collapse() routine below).
  214. #
  215.  
  216. sub build_tree {
  217.   my $self     = shift;
  218.   my $filename = shift;
  219.   my $string   = shift;
  220.  
  221.  
  222.   {
  223.     local($^W) = 0;      # Suppress warning from Expat.pm re File::Spec::load()
  224.     require XML::Parser; # We didn't need it until now
  225.   }
  226.  
  227.   my $xp = new XML::Parser(Style => 'Tree', @{$self->{opt}->{parseropts}});
  228.   my($tree);
  229.  
  230.  
  231.   # Work around wierd read error problem in expat with '-'
  232.  
  233.   if($filename  and  $filename eq '-') {
  234.     local($/) = undef;
  235.     $string = <STDIN>;
  236.     $filename = undef;
  237.   }
  238.   if($filename) {
  239.     # $tree = $xp->parsefile($filename);  # Changed due to prob w/mod_perl
  240.     local(*XML_FILE);
  241.     open(XML_FILE, "<$filename") || croak qq($filename - $!);
  242.     $tree = $xp->parse(*XML_FILE);
  243.     close(XML_FILE);
  244.   }
  245.   else {
  246.     $tree = $xp->parse($string);
  247.   }
  248.  
  249.   return($tree);
  250. }
  251.  
  252.  
  253. ##############################################################################
  254. # Sub: StorableSave()
  255. #
  256. # Wrapper routine for invoking Storable::nstore() to cache a parsed data
  257. # structure.
  258. #
  259.  
  260. sub StorableSave {
  261.   my($data, $filename) = @_;
  262.  
  263.   my $cachefile = $filename;
  264.   $cachefile =~ s{(\.xml)?$}{.stor};
  265.  
  266.   require Storable;           # We didn't need it until now
  267.   
  268.   Storable::nstore($data, $cachefile);
  269.   
  270. }
  271.  
  272.  
  273. ##############################################################################
  274. # Sub: StorableRestore()
  275. #
  276. # Wrapper routine for invoking Storable::retrieve() to read a cached parsed
  277. # data structure.  Only returns cached data if the cache file exists and is
  278. # newer than the source XML file.
  279. #
  280.  
  281. sub StorableRestore {
  282.   my($filename) = @_;
  283.   
  284.   my $cachefile = $filename;
  285.   $cachefile =~ s{(\.xml)?$}{.stor};
  286.  
  287.   return unless(-r $cachefile);
  288.   return unless((stat($cachefile))[9] > (stat($filename))[9]);
  289.  
  290.   unless($INC{'Storable.pm'}) {
  291.     require Storable;           # We didn't need it until now
  292.   }
  293.   
  294.   return(Storable::retrieve($cachefile));
  295.   
  296. }
  297.  
  298.  
  299. ##############################################################################
  300. # Sub: MemShareSave()
  301. #
  302. # Takes the supplied data structure reference and stores it away in a global
  303. # hash structure.
  304. #
  305.  
  306. sub MemShareSave {
  307.   my($data, $filename) = @_;
  308.  
  309.   lock(%MemShareCache);
  310.   $MemShareCache{$filename} = [time(), $data];
  311. }
  312.  
  313.  
  314. ##############################################################################
  315. # Sub: MemShareRestore()
  316. #
  317. # Takes a filename and looks in a global hash for a cached parsed version.
  318. #
  319.  
  320. sub MemShareRestore {
  321.   my($filename) = @_;
  322.   
  323.   lock(%MemShareCache);
  324.   return unless($MemShareCache{$filename});
  325.   return unless($MemShareCache{$filename}->[0] > (stat($filename))[9]);
  326.  
  327.   return($MemShareCache{$filename}->[1]);
  328.   
  329. }
  330.  
  331.  
  332. ##############################################################################
  333. # Sub: MemCopySave()
  334. #
  335. # Takes the supplied data structure and stores a copy of it in a global hash
  336. # structure.
  337. #
  338.  
  339. sub MemCopySave {
  340.   my($data, $filename) = @_;
  341.  
  342.   lock(%MemCopyCache);
  343.   unless($INC{'Storable.pm'}) {
  344.     require Storable;           # We didn't need it until now
  345.   }
  346.   
  347.   $MemCopyCache{$filename} = [time(), Storable::dclone($data)];
  348. }
  349.  
  350.  
  351. ##############################################################################
  352. # Sub: MemCopyRestore()
  353. #
  354. # Takes a filename and looks in a global hash for a cached parsed version.
  355. # Returns a reference to a copy of that data structure.
  356. #
  357.  
  358. sub MemCopyRestore {
  359.   my($filename) = @_;
  360.   
  361.   lock(%MemCopyCache);
  362.   return unless($MemCopyCache{$filename});
  363.   return unless($MemCopyCache{$filename}->[0] > (stat($filename))[9]);
  364.  
  365.   return(Storable::dclone($MemCopyCache{$filename}->[1]));
  366.   
  367. }
  368.  
  369.  
  370. ##############################################################################
  371. # Sub/Method: XMLout()
  372. #
  373. # Exported routine for 'unslurping' a data structure out to XML.
  374. #
  375. # Expects a reference to a data structure and an optional list of option
  376. # name => value pairs.
  377. #
  378.  
  379. sub XMLout {
  380.  
  381.   # If this is not a method call, create an object
  382.  
  383.   my $self;
  384.   if($_[0]  and  UNIVERSAL::isa($_[0], 'XML::Simple')) {
  385.     $self = shift;
  386.   }
  387.   else {
  388.     $self = new XML::Simple();
  389.   }
  390.  
  391.  
  392.   my $ref = shift;
  393.  
  394.   $self->handle_options('out', @_);
  395.  
  396.  
  397.   # Wrap top level arrayref in a hash
  398.  
  399.   if(ref($ref) eq 'ARRAY') {
  400.     $ref = { anon => $ref };
  401.   }
  402.  
  403.  
  404.   # Extract rootname from top level hash if keeproot enabled
  405.  
  406.   if($self->{opt}->{keeproot}) {
  407.     my(@keys) = keys(%$ref);
  408.     if(@keys == 1) {
  409.       $ref = $ref->{$keys[0]};
  410.       $self->{opt}->{rootname} = $keys[0];
  411.     }
  412.   }
  413.   
  414.   # Ensure there are no top level attributes if we're not adding root elements
  415.  
  416.   elsif($self->{opt}->{rootname} eq '') {
  417.     if(ref($ref) eq 'HASH') {
  418.       my $refsave = $ref;
  419.       $ref = {};
  420.       foreach (keys(%$refsave)) {
  421.     if(ref($refsave->{$_})) {
  422.       $ref->{$_} = $refsave->{$_};
  423.     }
  424.     else {
  425.       $ref->{$_} = [ $refsave->{$_} ];
  426.     }
  427.       }
  428.     }
  429.   }
  430.  
  431.  
  432.   # Encode the hashref and write to file if necessary
  433.  
  434.   my $xml = $self->value_to_xml($ref, $self->{opt}->{rootname}, {}, '');
  435.   if($self->{opt}->{xmldecl}) {
  436.     $xml = $self->{opt}->{xmldecl} . "\n" . $xml;
  437.   }
  438.  
  439.   if($self->{opt}->{outputfile}) {
  440.     if(ref($self->{opt}->{outputfile})) {
  441.       return($self->{opt}->{outputfile}->print($xml));
  442.     }
  443.     else {
  444.       open(_XML_SIMPLE_OUT_, ">$self->{opt}->{outputfile}") ||
  445.         croak "open($self->{opt}->{outputfile}): $!";
  446.       print _XML_SIMPLE_OUT_ $xml || croak "print: $!";
  447.       close(_XML_SIMPLE_OUT_);
  448.     }
  449.   }
  450.   else {
  451.     return($xml);
  452.   }
  453. }
  454.  
  455.  
  456. ##############################################################################
  457. # Method: handle_options()
  458. #
  459. # Helper routine for both XMLin() and XMLout().  Both routines handle their
  460. # first argument and assume all other args are options handled by this routine.
  461. # Saves a hash of options in $self->{opt}.
  462. #
  463. # If default options were passed to the constructor, they will be retrieved
  464. # here and merged with options supplied to the method call.
  465. #
  466. # First argument should be the string 'in' or the string 'out'.
  467. #
  468. # Remaining arguments should be name=>value pairs.  Sets up default values
  469. # for options not supplied.  Unrecognised options are a fatal error.
  470. #
  471.  
  472. sub handle_options  {
  473.   my $self = shift;
  474.   my $dirn = shift;
  475.  
  476.  
  477.   lock($DefaultValues);
  478.  
  479.   # Determine valid options based on context
  480.  
  481.   my %known_opt; 
  482.   if($dirn eq 'in') {
  483.     @known_opt{@KnownOptIn} = @KnownOptIn;
  484.   }
  485.   else {
  486.     @known_opt{@KnownOptOut} = @KnownOptOut;
  487.   }
  488.  
  489.  
  490.   # Store supplied options in hashref and weed out invalid ones
  491.  
  492.   if(@_ % 2) {
  493.     croak "Options must be name=>value pairs (odd number supplied)";
  494.   }
  495.   my $opt = { @_ };
  496.   $self->{opt} = $opt;
  497.  
  498.   foreach (keys(%$opt)) {
  499.     croak "Unrecognised option: $_"
  500.       unless($known_opt{$_});
  501.   }
  502.  
  503.  
  504.   # Merge in options passed to constructor
  505.  
  506.   if($self->{defopt}) {
  507.     foreach (keys(%known_opt)) {
  508.       unless(exists($opt->{$_})) {
  509.     if(exists($self->{defopt}->{$_})) {
  510.       $opt->{$_} = $self->{defopt}->{$_};
  511.     }
  512.       }
  513.     }
  514.   }
  515.  
  516.  
  517.   # Set sensible defaults if not supplied
  518.   
  519.   if(exists($opt->{rootname})) {
  520.     unless(defined($opt->{rootname})) {
  521.       $opt->{rootname} = '';
  522.     }
  523.   }
  524.   else {
  525.     $opt->{rootname} = $DefRootName;
  526.   }
  527.   
  528.   if($opt->{xmldecl}  and  $opt->{xmldecl} eq '1') {
  529.     $opt->{xmldecl} = $DefXmlDecl;
  530.   }
  531.  
  532.   unless(exists($opt->{contentkey})) {
  533.     $opt->{contentkey} = $DefContentKey;
  534.   }
  535.  
  536.  
  537.   # Cleanups for values assumed to be arrays later
  538.  
  539.   if($opt->{searchpath}) {
  540.     unless(ref($opt->{searchpath})) {
  541.       $opt->{searchpath} = [ $opt->{searchpath} ];
  542.     }
  543.   }
  544.   else  {
  545.     $opt->{searchpath} = [ ];
  546.   }
  547.  
  548.   if($opt->{cache}  and !ref($opt->{cache})) {
  549.     $opt->{cache} = [ $opt->{cache} ];
  550.   }
  551.   
  552.   unless(exists($opt->{parseropts})) {
  553.     $opt->{parseropts} = [ ];
  554.   }
  555.  
  556.  
  557.   # Special cleanup for {keyattr} which could be arrayref or hashref or left
  558.   # to default to arrayref
  559.  
  560.   if(exists($opt->{keyattr}))  {
  561.     if(ref($opt->{keyattr})) {
  562.       if(ref($opt->{keyattr}) eq 'HASH') {
  563.  
  564.     # Make a copy so we can mess with it
  565.  
  566.     $opt->{keyattr} = { %{$opt->{keyattr}} };
  567.  
  568.     
  569.     # Convert keyattr => { elem => '+attr' }
  570.     # to keyattr => { elem => [ 'attr', '+' ] } 
  571.  
  572.     foreach (keys(%{$opt->{keyattr}})) {
  573.       if($opt->{keyattr}->{$_} =~ /^(\+|-)?(.*)$/) {
  574.         $opt->{keyattr}->{$_} = [ $2, ($1 ? $1 : '') ];
  575.       }
  576.       else {
  577.         delete($opt->{keyattr}->{$_}); # Never reached (famous last words?)
  578.       }
  579.     }
  580.       }
  581.       else {
  582.     if(@{$opt->{keyattr}} == 0) {
  583.       delete($opt->{keyattr});
  584.     }
  585.       }
  586.     }
  587.     else {
  588.       $opt->{keyattr} = [ $opt->{keyattr} ];
  589.     }
  590.   }
  591.   else  {
  592.     $opt->{keyattr} = [ @DefKeyAttr ];
  593.   }
  594.  
  595.   
  596.   # Special cleanup for {forcearray} which could be arrayref or boolean
  597.   # or left to default to 0
  598.  
  599.   if(exists($opt->{forcearray})) {
  600.     if(ref($opt->{forcearray}) eq 'ARRAY') {
  601.       if(@{$opt->{forcearray}}) {
  602.         $opt->{forcearray} = { (
  603.       map { $_ => 1 } @{$opt->{forcearray}}
  604.     ) };
  605.       }
  606.       else {
  607.         $opt->{forcearray} = 0;
  608.       }
  609.     }
  610.     else {
  611.       $opt->{forcearray} = ( $opt->{forcearray} ? 1 : 0 );
  612.     }
  613.   }
  614.   else {
  615.     $opt->{forcearray} = 0;
  616.   }
  617.  
  618. }
  619.  
  620.  
  621. ##############################################################################
  622. # Method: find_xml_file()
  623. #
  624. # Helper routine for XMLin().
  625. # Takes a filename, and a list of directories, attempts to locate the file in
  626. # the directories listed.
  627. # Returns a full pathname on success; croaks on failure.
  628. #
  629.  
  630. sub find_xml_file  {
  631.   my $self = shift;
  632.   my $file = shift;
  633.   my @search_path = @_;
  634.  
  635.  
  636.   my($filename, $filedir) =
  637.     File::Basename::fileparse($file);
  638.  
  639.   if($filename ne $file) {        # Ignore searchpath if dir component
  640.     return($file) if(-e $file);
  641.   }
  642.   else {
  643.     my($path);
  644.     foreach $path (@search_path)  {
  645.       my $fullpath = File::Spec->catfile($path, $file);
  646.       return($fullpath) if(-e $fullpath);
  647.     }
  648.   }
  649.  
  650.   croak "Could not find $file in ", join(':', @search_path);
  651. }
  652.  
  653.  
  654. ##############################################################################
  655. # Method: collapse()
  656. #
  657. # Helper routine for XMLin().  This routine really comprises the 'smarts' (or
  658. # value add) of this module.
  659. #
  660. # Takes the parse tree that XML::Parser produced from the supplied XML and
  661. # recurses through it 'collapsing' unnecessary levels of indirection (nested
  662. # arrays etc) to produce a data structure that is easier to work with.
  663. #
  664. # Elements in the original parser tree are represented as an element name
  665. # followed by an arrayref.  The first element of the array is a hashref
  666. # containing the attributes.  The rest of the array contains a list of any
  667. # nested elements as name+arrayref pairs:
  668. #
  669. #  <element name>, [ { <attribute hashref> }, <element name>, [ ... ], ... ]
  670. #
  671. # The special element name '0' (zero) flags text content.
  672. #
  673. # This routine cuts down the noise by discarding any text content consisting of
  674. # only whitespace and then moves the nested elements into the attribute hash
  675. # using the name of the nested element as the hash key and the collapsed
  676. # version of the nested element as the value.  Multiple nested elements with
  677. # the same name will initially be represented as an arrayref, but this may be
  678. # 'folded' into a hashref depending on the value of the keyattr option.
  679. #
  680.  
  681. sub collapse {
  682.   my $self = shift;;
  683.  
  684.  
  685.   # Start with the hash of attributes
  686.   
  687.   my $attr  = shift;
  688.   $attr = {} if($self->{opt}->{noattr});    # Discard if 'noattr' set
  689.  
  690.  
  691.   # Add any nested elements
  692.  
  693.   my($key, $val);
  694.   while(@_) {
  695.     $key = shift;
  696.     $val = shift;
  697.  
  698.     if(ref($val)) {
  699.       $val = $self->collapse(@$val);
  700.       next if(!defined($val)  and  $self->{opt}->{suppressempty});
  701.     }
  702.     elsif($key eq '0') {
  703.       next if($val =~ m{^\s*$}s);  # Skip all whitespace content
  704.       if(!%$attr  and  !@_) {      # Short circuit text in tag with no attr
  705.         return($self->{opt}->{forcecontent} ?
  706.            { $self->{opt}->{contentkey} => $val } : $val
  707.           );
  708.       }
  709.       $key = $self->{opt}->{contentkey};
  710.     }
  711.  
  712.  
  713.     # Combine duplicate attributes into arrayref if required
  714.  
  715.     if(exists($attr->{$key})) {
  716.       if(ref($attr->{$key}) eq 'ARRAY') {
  717.         push(@{$attr->{$key}}, $val);
  718.       }
  719.       else {
  720.         $attr->{$key} = [ $attr->{$key}, $val ];
  721.       }
  722.     }
  723.     elsif(ref($val) eq 'ARRAY') {  # Handle anonymous arrays
  724.       $attr->{$key} = [ $val ];
  725.     }
  726.     else {
  727.       if( $key ne $self->{opt}->{contentkey}  and
  728.           (
  729.         ($self->{opt}->{forcearray} == 1) or
  730.         ( 
  731.           (ref($self->{opt}->{forcearray}) eq 'HASH') and
  732.           ($self->{opt}->{forcearray}->{$key})
  733.         )
  734.       )
  735.     ) {
  736.     $attr->{$key} = [ $val ];
  737.       }
  738.       else {
  739.     $attr->{$key} = $val;
  740.       }
  741.     }
  742.   }
  743.  
  744.  
  745.   # Turn arrayrefs into hashrefs if key fields present
  746.  
  747.   my $count = 0;
  748.   if($self->{opt}->{keyattr}) {
  749.     while(($key,$val) = each %$attr) {
  750.       if(ref($val) eq 'ARRAY') {
  751.     $attr->{$key} = $self->array_to_hash($key, $val);
  752.       }
  753.       $count++;
  754.     }
  755.   }
  756.  
  757.  
  758.   # Fold hashes containing a single anonymous array up into just the array
  759.  
  760.   if($count == 1  and  ref($attr->{anon}) eq 'ARRAY') {
  761.     return($attr->{anon});
  762.   }
  763.  
  764.  
  765.   # Do the right thing if hash is empty, otherwise just return it
  766.  
  767.   if(!%$attr  and  exists($self->{opt}->{suppressempty})) {
  768.     if(defined($self->{opt}->{suppressempty})  and
  769.        $self->{opt}->{suppressempty} eq '') {
  770.       return('');
  771.     }
  772.     return(undef);
  773.   }
  774.  
  775.   return($attr)
  776.  
  777. }
  778.  
  779.  
  780. ##############################################################################
  781. # Method: array_to_hash()
  782. #
  783. # Helper routine for collapse().
  784. # Attempts to 'fold' an array of hashes into an hash of hashes.  Returns a
  785. # reference to the hash on success or the original array if folding is
  786. # not possible.  Behaviour is controlled by 'keyattr' option.
  787. #
  788.  
  789. sub array_to_hash {
  790.   my $self     = shift;
  791.   my $name     = shift;
  792.   my $arrayref = shift;
  793.  
  794.   my $hashref  = {};
  795.  
  796.   my($i, $key, $val, $flag);
  797.  
  798.  
  799.   # Handle keyattr => { .... }
  800.  
  801.   if(ref($self->{opt}->{keyattr}) eq 'HASH') {
  802.     return($arrayref) unless(exists($self->{opt}->{keyattr}->{$name}));
  803.     ($key, $flag) = @{$self->{opt}->{keyattr}->{$name}};
  804.     for($i = 0; $i < @$arrayref; $i++)  {
  805.       if(ref($arrayref->[$i]) eq 'HASH' and exists($arrayref->[$i]->{$key})) {
  806.     $val = $arrayref->[$i]->{$key};
  807.     $hashref->{$val} = { %{$arrayref->[$i]} };
  808.     $hashref->{$val}->{"-$key"} = $hashref->{$val}->{$key} if($flag eq '-');
  809.     delete $hashref->{$val}->{$key} unless($flag eq '+');
  810.       }
  811.       else {
  812.     carp "Warning: <$name> element has no '$key' key attribute" if($^W);
  813.     return($arrayref);
  814.       }
  815.     }
  816.   }
  817.  
  818.  
  819.   # Or assume keyattr => [ .... ]
  820.  
  821.   else {
  822.     ELEMENT: for($i = 0; $i < @$arrayref; $i++)  {
  823.       return($arrayref) unless(ref($arrayref->[$i]) eq 'HASH');
  824.  
  825.       foreach $key (@{$self->{opt}->{keyattr}}) {
  826.     if(defined($arrayref->[$i]->{$key}))  {
  827.       $val = $arrayref->[$i]->{$key};
  828.       $hashref->{$val} = { %{$arrayref->[$i]} };
  829.       delete $hashref->{$val}->{$key};
  830.       next ELEMENT;
  831.     }
  832.       }
  833.  
  834.       return($arrayref);    # No keyfield matched
  835.     }
  836.   }
  837.  
  838.   return($hashref);
  839. }
  840.  
  841.  
  842. ##############################################################################
  843. # Method: value_to_xml()
  844. #
  845. # Helper routine for XMLout() - recurses through a data structure building up
  846. # and returning an XML representation of that structure as a string.
  847. # Arguments expected are:
  848. # - the data structure to be encoded (usually a reference)
  849. # - the XML tag name to use for this item
  850. # - a hashref of references already encoded (to detect recursive structures)
  851. # - a string of spaces for use as the current indent level
  852. #
  853.  
  854. sub value_to_xml {
  855.   my $self = shift;;
  856.  
  857.  
  858.   # Grab the other arguments
  859.  
  860.   my($ref, $name, $encoded, $indent) = @_;
  861.  
  862.   my $named = (defined($name) and $name ne '' ? 1 : 0);
  863.  
  864.   my $nl = "\n";
  865.  
  866.   if(ref($ref)) {
  867.     croak "recursive data structures not supported" if($encoded->{$ref});
  868.     $encoded->{$ref} = $ref;
  869.   }
  870.   else {
  871.     if($named) {
  872.       return(join('',
  873.               $indent, '<', $name, '>',
  874.           ($self->{opt}->{noescape} ? $ref : $self->escape_value($ref)),
  875.               '</', $name, ">", $nl
  876.         ));
  877.     }
  878.     else {
  879.       return("$ref$nl");
  880.     }
  881.   }
  882.  
  883.   # Unfold hash to array if possible
  884.  
  885.   if(ref($ref) eq 'HASH'               # It is a hash
  886.      and %$ref                         # and it's not empty
  887.      and $self->{opt}->{keyattr}       # and folding is enabled
  888.      and $indent                       # and its not the root element
  889.   ) {
  890.     $ref = $self->hash_to_array($name, $ref);
  891.   }
  892.  
  893.   
  894.   my @result = ();
  895.   my($key, $value);
  896.  
  897.  
  898.   # Handle hashrefs
  899.  
  900.   if(ref($ref) eq 'HASH') {
  901.     my @nested = ();
  902.     my $text_content = undef;
  903.     if($named) {
  904.       push @result, $indent, '<', $name;
  905.     }
  906.  
  907.     if(%$ref) {
  908.       while(($key, $value) = each(%$ref)) {
  909.     next if(substr($key, 0, 1) eq '-');
  910.     if(!defined($value)) {
  911.       unless(exists($self->{opt}->{suppressempty})
  912.          and !defined($self->{opt}->{suppressempty})
  913.       ) {
  914.         carp 'Use of uninitialized value';
  915.       }
  916.       $value = {};
  917.     }
  918.     if(ref($value)  or  $self->{opt}->{noattr}) {
  919.       push @nested,
  920.         $self->value_to_xml($value, $key, $encoded, "$indent  ");
  921.     }
  922.     else {
  923.       $value = $self->escape_value($value) unless($self->{opt}->{noescape});
  924.       if($key eq $self->{opt}->{contentkey}) {
  925.         $text_content = $value;
  926.       }
  927.       else {
  928.         push @result, ' ', $key, '="', $value , '"';
  929.       }
  930.     }
  931.       }
  932.     }
  933.     else {
  934.       $text_content = '';
  935.     }
  936.  
  937.     if(@nested  or  defined($text_content)) {
  938.       if($named) {
  939.         push @result, ">";
  940.     if(defined($text_content)) {
  941.       push @result, $text_content;
  942.       $nested[0] =~ s/^\s+// if(@nested);
  943.     }
  944.     else {
  945.       push @result, $nl;
  946.     }
  947.     if(@nested) {
  948.       push @result, @nested, $indent;
  949.     }
  950.     push @result, '</', $name, ">", $nl;
  951.       }
  952.       else {
  953.         push @result, @nested;             # Special case if no root elements
  954.       }
  955.     }
  956.     else {
  957.       push @result, " />", $nl;
  958.     }
  959.   }
  960.  
  961.  
  962.   # Handle arrayrefs
  963.  
  964.   elsif(ref($ref) eq 'ARRAY') {
  965.     foreach $value (@$ref) {
  966.       if(!ref($value)) {
  967.         push @result,
  968.          $indent, '<', $name, '>',
  969.          ($self->{opt}->{noescape} ? $value : $self->escape_value($value)),
  970.          '</', $name, ">\n";
  971.       }
  972.       elsif(ref($value) eq 'HASH') {
  973.     push @result, $self->value_to_xml($value, $name, $encoded, $indent);
  974.       }
  975.       else {
  976.     push @result,
  977.            $indent, '<', $name, ">\n",
  978.            $self->value_to_xml($value, 'anon', $encoded, "$indent  "),
  979.            $indent, '</', $name, ">\n";
  980.       }
  981.     }
  982.   }
  983.  
  984.   else {
  985.     croak "Can't encode a value of type: " . ref($ref);
  986.   }
  987.  
  988.   return(join('', @result));
  989. }
  990.  
  991.  
  992. ##############################################################################
  993. # Method: escape_value()
  994. #
  995. # Helper routine for automatically escaping values for XMLout().
  996. # Expects a scalar data value.  Returns escaped version.
  997. #
  998.  
  999. sub escape_value {
  1000.   my $self = shift;
  1001.  
  1002.   my($data) = @_;
  1003.  
  1004.   $data =~ s/&/&/sg;
  1005.   $data =~ s/</</sg;
  1006.   $data =~ s/>/>/sg;
  1007.   $data =~ s/"/"/sg;
  1008.  
  1009.   return($data);
  1010. }
  1011.  
  1012.  
  1013. ##############################################################################
  1014. # Method: hash_to_array()
  1015. #
  1016. # Helper routine for value_to_xml().
  1017. # Attempts to 'unfold' a hash of hashes into an array of hashes.  Returns a
  1018. # reference to the array on success or the original hash if unfolding is
  1019. # not possible.
  1020. #
  1021.  
  1022. sub hash_to_array {
  1023.   my $self    = shift;
  1024.   my $parent  = shift;
  1025.   my $hashref = shift;
  1026.  
  1027.   my $arrayref = [];
  1028.  
  1029.   my($key, $value);
  1030.  
  1031.   foreach $key (keys(%$hashref)) {
  1032.     $value = $hashref->{$key};
  1033.     return($hashref) unless(ref($value) eq 'HASH');
  1034.  
  1035.     if(ref($self->{opt}->{keyattr}) eq 'HASH') {
  1036.       return($hashref) unless(defined($self->{opt}->{keyattr}->{$parent}));
  1037.       push(@$arrayref, { $self->{opt}->{keyattr}->{$parent}->[0] => $key,
  1038.                          %$value });
  1039.     }
  1040.     else {
  1041.       push(@$arrayref, { $self->{opt}->{keyattr}->[0] => $key, %$value });
  1042.     }
  1043.   }
  1044.  
  1045.   return($arrayref);
  1046. }
  1047.  
  1048. 1;
  1049.  
  1050. __END__
  1051.  
  1052. =head1 QUICK START
  1053.  
  1054. Say you have a script called B<foo> and a file of configuration options
  1055. called B<foo.xml> containing this:
  1056.  
  1057.   <config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
  1058.     <server name="sahara" osname="solaris" osversion="2.6">
  1059.       <address>10.0.0.101</address>
  1060.       <address>10.0.1.101</address>
  1061.     </server>
  1062.     <server name="gobi" osname="irix" osversion="6.5">
  1063.       <address>10.0.0.102</address>
  1064.     </server>
  1065.     <server name="kalahari" osname="linux" osversion="2.0.34">
  1066.       <address>10.0.0.103</address>
  1067.       <address>10.0.1.103</address>
  1068.     </server>
  1069.   </config>
  1070.  
  1071. The following lines of code in B<foo>:
  1072.  
  1073.   use XML::Simple;
  1074.  
  1075.   my $config = XMLin();
  1076.  
  1077. will 'slurp' the configuration options into the hashref $config (because no
  1078. arguments are passed to C<XMLin()> the name and location of the XML file will
  1079. be inferred from name and location of the script).  You can dump out the
  1080. contents of the hashref using Data::Dumper:
  1081.  
  1082.   use Data::Dumper;
  1083.  
  1084.   print Dumper($config);
  1085.  
  1086. which will produce something like this (formatting has been adjusted for
  1087. brevity):
  1088.  
  1089.   {
  1090.       'logdir'        => '/var/log/foo/',
  1091.       'debugfile'     => '/tmp/foo.debug',
  1092.       'server'        => {
  1093.       'sahara'        => {
  1094.           'osversion'     => '2.6',
  1095.           'osname'        => 'solaris',
  1096.           'address'       => [ '10.0.0.101', '10.0.1.101' ]
  1097.       },
  1098.       'gobi'          => {
  1099.           'osversion'     => '6.5',
  1100.           'osname'        => 'irix',
  1101.           'address'       => '10.0.0.102'
  1102.       },
  1103.       'kalahari'      => {
  1104.           'osversion'     => '2.0.34',
  1105.           'osname'        => 'linux',
  1106.           'address'       => [ '10.0.0.103', '10.0.1.103' ]
  1107.       }
  1108.       }
  1109.   }
  1110.  
  1111. Your script could then access the name of the log directory like this:
  1112.  
  1113.   print $config->{logdir};
  1114.  
  1115. similarly, the second address on the server 'kalahari' could be referenced as:
  1116.  
  1117.   print $config->{server}->{kalahari}->{address}->[1];
  1118.  
  1119. What could be simpler?  (Rhetorical).
  1120.  
  1121. For simple requirements, that's really all there is to it.  If you want to
  1122. store your XML in a different directory or file, or pass it in as a string or
  1123. even pass it in via some derivative of an IO::Handle, you'll need to check out
  1124. L<"OPTIONS">.  If you want to turn off or tweak the array folding feature (that
  1125. neat little transformation that produced $config->{server}) you'll find options
  1126. for that as well.
  1127.  
  1128. If you want to generate XML (for example to write a modified version of
  1129. $config back out as XML), check out C<XMLout()>.
  1130.  
  1131. If your needs are not so simple, this may not be the module for you.  In that
  1132. case, you might want to read L<"WHERE TO FROM HERE?">.
  1133.  
  1134. =head1 DESCRIPTION
  1135.  
  1136. The XML::Simple module provides a simple API layer on top of the XML::Parser
  1137. module.  Two functions are exported: C<XMLin()> and C<XMLout()>.
  1138.  
  1139. The most common approach is to simply call these two functions directly, but an
  1140. optional object oriented interface (see L<"OPTIONAL OO INTERFACE"> below)
  1141. allows them to be called as methods of an B<XML::Simple> object.
  1142.  
  1143. =head2 XMLin()
  1144.  
  1145. Parses XML formatted data and returns a reference to a data structure which
  1146. contains the same information in a more readily accessible form.  (Skip
  1147. down to L<"EXAMPLES"> below, for more sample code).
  1148.  
  1149. C<XMLin()> accepts an optional XML specifier followed by zero or more 'name =>
  1150. value' option pairs.  The XML specifier can be one of the following:
  1151.  
  1152. =over 4
  1153.  
  1154. =item A filename
  1155.  
  1156. If the filename contains no directory components C<XMLin()> will look for the
  1157. file in each directory in the searchpath (see L<"OPTIONS"> below).  eg:
  1158.  
  1159.   $ref = XMLin('/etc/params.xml');
  1160.  
  1161. Note, the filename '-' can be used to parse from STDIN.
  1162.  
  1163. =item undef
  1164.  
  1165. If there is no XML specifier, C<XMLin()> will check the script directory and
  1166. each of the searchpath directories for a file with the same name as the script
  1167. but with the extension '.xml'.  Note: if you wish to specify options, you
  1168. must specify the value 'undef'.  eg:
  1169.  
  1170.   $ref = XMLin(undef, forcearray => 1);
  1171.  
  1172. =item A string of XML
  1173.  
  1174. A string containing XML (recognised by the presence of '<' and '>' characters)
  1175. will be parsed directly.  eg:
  1176.  
  1177.   $ref = XMLin('<opt username="bob" password="flurp" />');
  1178.  
  1179. =item An IO::Handle object
  1180.  
  1181. An IO::Handle object will be read to EOF and its contents parsed. eg:
  1182.  
  1183.   $fh = new IO::File('/etc/params.xml');
  1184.   $ref = XMLin($fh);
  1185.  
  1186. =back
  1187.  
  1188. =head2 XMLout()
  1189.  
  1190. Takes a data structure (generally a hashref) and returns an XML encoding of
  1191. that structure.  If the resulting XML is parsed using C<XMLin()>, it will
  1192. return a data structure equivalent to the original. 
  1193.  
  1194. When translating hashes to XML, hash keys which have a leading '-' will be
  1195. silently skipped.  This is the approved method for marking elements of a
  1196. data structure which should be ignored by C<XMLout>.  (Note: If these items
  1197. were not skipped the key names would be emitted as element or attribute names
  1198. with a leading '-' which would not be valid XML).
  1199.  
  1200. =head2 Caveats
  1201.  
  1202. Some care is required in creating data structures which will be passed to
  1203. C<XMLout()>.  Hash keys from the data structure will be encoded as either XML
  1204. element names or attribute names.  Therefore, you should use hash key names 
  1205. which conform to the relatively strict XML naming rules:
  1206.  
  1207. Names in XML must begin with a letter.  The remaining characters may be
  1208. letters, digits, hyphens (-), underscores (_) or full stops (.).  It is also
  1209. allowable to include one colon (:) in an element name but this should only be
  1210. used when working with namespaces - a facility well beyond the scope of
  1211. B<XML::Simple>.
  1212.  
  1213. You can use other punctuation characters in hash values (just not in hash
  1214. keys) however B<XML::Simple> does not support dumping binary data.
  1215.  
  1216. If you break these rules, the current implementation of C<XMLout()> will 
  1217. simply emit non-compliant XML which will be rejected if you try to read it
  1218. back in.  (A later version of B<XML::Simple> might take a more proactive
  1219. approach).
  1220.  
  1221. Note also that although you can nest hashes and arrays to arbitrary levels,
  1222. recursive data structures are not supported and will cause C<XMLout()> to die.
  1223.  
  1224. Refer to L<"WHERE TO FROM HERE?"> if C<XMLout()> is too simple for your needs.
  1225.  
  1226.  
  1227. =head1 OPTIONS
  1228.  
  1229. B<XML::Simple> supports a number of options (in fact as each release of
  1230. B<XML::Simple> adds more options, the module's claim to the name 'Simple'
  1231. becomes more tenuous).  If you find yourself repeatedly having to specify
  1232. the same options, you might like to investigate L<"OPTIONAL OO INTERFACE">
  1233. below.
  1234.  
  1235. Because there are so many options, it's hard for new users to know which ones
  1236. are important, so here are the two you really need to know about:
  1237.  
  1238. =over 4
  1239.  
  1240. =item *
  1241.  
  1242. check out 'forcearray' because you'll almost certainly want to turn it on
  1243.  
  1244. =item *
  1245.  
  1246. make sure you know what the 'keyattr' option does and what its default value
  1247. is because it may surprise you otherwise
  1248.  
  1249. =back
  1250.  
  1251. Both C<XMLin()> and C<XMLout()> expect a single argument followed by a list of
  1252. options.  An option takes the form of a 'name => value' pair.  The options
  1253. listed below are marked with 'B<in>' if they are recognised by C<XMLin()> and
  1254. 'B<out>' if they are recognised by C<XMLout()>.
  1255.  
  1256. =over 4
  1257.  
  1258. =item keyattr => [ list ] (B<in+out>)
  1259.  
  1260. This option controls the 'array folding' feature which translates nested
  1261. elements from an array to a hash.  For example, this XML:
  1262.  
  1263.     <opt>
  1264.       <user login="grep" fullname="Gary R Epstein" />
  1265.       <user login="stty" fullname="Simon T Tyson" />
  1266.     </opt>
  1267.  
  1268. would, by default, parse to this:
  1269.  
  1270.     {
  1271.       'user' => [
  1272.           {
  1273.             'login' => 'grep',
  1274.             'fullname' => 'Gary R Epstein'
  1275.           },
  1276.           {
  1277.             'login' => 'stty',
  1278.             'fullname' => 'Simon T Tyson'
  1279.           }
  1280.         ]
  1281.     }
  1282.  
  1283. If the option 'keyattr => "login"' were used to specify that the 'login'
  1284. attribute is a key, the same XML would parse to:
  1285.  
  1286.     {
  1287.       'user' => {
  1288.           'stty' => {
  1289.                   'fullname' => 'Simon T Tyson'
  1290.                 },
  1291.           'grep' => {
  1292.                   'fullname' => 'Gary R Epstein'
  1293.                 }
  1294.         }
  1295.     }
  1296.  
  1297. The key attribute names should be supplied in an arrayref if there is more
  1298. than one.  C<XMLin()> will attempt to match attribute names in the order
  1299. supplied.  C<XMLout()> will use the first attribute name supplied when
  1300. 'unfolding' a hash into an array.
  1301.  
  1302. Note: the keyattr option controls the folding of arrays.  By default a single
  1303. nested element will be rolled up into a scalar rather than an array and
  1304. therefore will not be folded.  Use the 'forcearray' option (below) to force
  1305. nested elements to be parsed into arrays and therefore candidates for folding
  1306. into hashes.
  1307.  
  1308. The default value for 'keyattr' is ['name', 'key', 'id'].  Setting this option
  1309. to an empty list will disable the array folding feature.
  1310.  
  1311. =item keyattr => { list } (B<in+out>)
  1312.  
  1313. This alternative method of specifiying the key attributes allows more fine
  1314. grained control over which elements are folded and on which attributes.  For
  1315. example the option 'keyattr => { package => 'id' } will cause any package
  1316. elements to be folded on the 'id' attribute.  No other elements which have an
  1317. 'id' attribute will be folded at all. 
  1318.  
  1319. Note: C<XMLin()> will generate a warning if this syntax is used and an element
  1320. which does not have the specified key attribute is encountered (eg: a 'package'
  1321. element without an 'id' attribute, to use the example above).  Warnings will
  1322. only be generated if B<-w> is in force.
  1323.  
  1324. Two further variations are made possible by prefixing a '+' or a '-' character
  1325. to the attribute name:
  1326.  
  1327. The option 'keyattr => { user => "+login" }' will cause this XML:
  1328.  
  1329.     <opt>
  1330.       <user login="grep" fullname="Gary R Epstein" />
  1331.       <user login="stty" fullname="Simon T Tyson" />
  1332.     </opt>
  1333.  
  1334. to parse to this data structure:
  1335.  
  1336.     {
  1337.       'user' => {
  1338.           'stty' => {
  1339.                   'fullname' => 'Simon T Tyson',
  1340.                   'login'    => 'stty'
  1341.                 },
  1342.           'grep' => {
  1343.                   'fullname' => 'Gary R Epstein',
  1344.                   'login'    => 'grep'
  1345.                 }
  1346.         }
  1347.     }
  1348.  
  1349. The '+' indicates that the value of the key attribute should be copied rather than
  1350. moved to the folded hash key.
  1351.  
  1352. A '-' prefix would produce this result:
  1353.  
  1354.     {
  1355.       'user' => {
  1356.           'stty' => {
  1357.                   'fullname' => 'Simon T Tyson',
  1358.                   '-login'    => 'stty'
  1359.                 },
  1360.           'grep' => {
  1361.                   'fullname' => 'Gary R Epstein',
  1362.                   '-login'    => 'grep'
  1363.                 }
  1364.         }
  1365.     }
  1366.  
  1367. As described earlier, C<XMLout> will ignore hash keys starting with a '-'.
  1368.  
  1369. =item searchpath => [ list ] (B<in>)
  1370.  
  1371. Where the XML is being read from a file, and no path to the file is specified,
  1372. this attribute allows you to specify which directories should be searched.
  1373.  
  1374. If the first parameter to C<XMLin()> is undefined, the default searchpath
  1375. will contain only the directory in which the script itself is located.
  1376. Otherwise the default searchpath will be empty.  
  1377.  
  1378. Note: the current directory ('.') is B<not> searched unless it is the directory
  1379. containing the script.
  1380.  
  1381. =item forcearray => 1 (B<in>)
  1382.  
  1383. This option should be set to '1' to force nested elements to be represented
  1384. as arrays even when there is only one.  Eg, with forcearray enabled, this
  1385. XML:
  1386.  
  1387.     <opt>
  1388.       <name>value</name>
  1389.     </opt>
  1390.  
  1391. would parse to this:
  1392.  
  1393.     {
  1394.       'name' => [
  1395.           'value'
  1396.         ]
  1397.     }
  1398.  
  1399. instead of this (the default):
  1400.  
  1401.     {
  1402.       'name' => 'value'
  1403.     }
  1404.  
  1405. This option is especially useful if the data structure is likely to be written
  1406. back out as XML and the default behaviour of rolling single nested elements up
  1407. into attributes is not desirable. 
  1408.  
  1409. If you are using the array folding feature, you should almost certainly enable
  1410. this option.  If you do not, single nested elements will not be parsed to
  1411. arrays and therefore will not be candidates for folding to a hash.  (Given that
  1412. the default value of 'keyattr' enables array folding, the default value of this
  1413. option should probably also have been enabled too - sorry).
  1414.  
  1415. =item forcearray => [ name(s) ] (B<in>)
  1416.  
  1417. This alternative form of the 'forcearray' option allows you to specify a list
  1418. of element names which should always be forced into an array representation,
  1419. rather than the 'all or nothing' approach above.
  1420.  
  1421. =item noattr => 1 (B<in+out>)
  1422.  
  1423. When used with C<XMLout()>, the generated XML will contain no attributes.
  1424. All hash key/values will be represented as nested elements instead.
  1425.  
  1426. When used with C<XMLin()>, any attributes in the XML will be ignored.
  1427.  
  1428. =item suppressempty => 1 | '' | undef (B<in>)
  1429.  
  1430. This option controls what C<XMLin()> should do with empty elements (no
  1431. attributes and no content).  The default behaviour is to represent them as
  1432. empty hashes.  Setting this option to a true value (eg: 1) will cause empty
  1433. elements to be skipped altogether.  Setting the option to 'undef' or the empty
  1434. string will cause empty elements to be represented as the undefined value or
  1435. the empty string respectively.  The latter two alternatives are a little
  1436. easier to test for in your code than a hash with no keys.
  1437.  
  1438. =item cache => [ cache scheme(s) ] (B<in>)
  1439.  
  1440. Because loading the B<XML::Parser> module and parsing an XML file can consume a
  1441. significant number of CPU cycles, it is often desirable to cache the output of
  1442. C<XMLin()> for later reuse.
  1443.  
  1444. When parsing from a named file, B<XML::Simple> supports a number of caching
  1445. schemes.  The 'cache' option may be used to specify one or more schemes (using
  1446. an anonymous array).  Each scheme will be tried in turn in the hope of finding
  1447. a cached pre-parsed representation of the XML file.  If no cached copy is
  1448. found, the file will be parsed and the first cache scheme in the list will be
  1449. used to save a copy of the results.  The following cache schemes have been
  1450. implemented:
  1451.  
  1452. =over 4
  1453.  
  1454. =item storable
  1455.  
  1456. Utilises B<Storable.pm> to read/write a cache file with the same name as the
  1457. XML file but with the extension .stor
  1458.  
  1459. =item memshare
  1460.  
  1461. When a file is first parsed, a copy of the resulting data structure is retained
  1462. in memory in the B<XML::Simple> module's namespace.  Subsequent calls to parse
  1463. the same file will return a reference to this structure.  This cached version
  1464. will persist only for the life of the Perl interpreter (which in the case of
  1465. mod_perl for example, may be some significant time).
  1466.  
  1467. Because each caller receives a reference to the same data structure, a change
  1468. made by one caller will be visible to all.  For this reason, the reference
  1469. returned should be treated as read-only.
  1470.  
  1471. =item memcopy
  1472.  
  1473. This scheme works identically to 'memshare' (above) except that each caller
  1474. receives a reference to a new data structure which is a copy of the cached
  1475. version.  Copying the data structure will add a little processing overhead,
  1476. therefore this scheme should only be used where the caller intends to modify
  1477. the data structure (or wishes to protect itself from others who might).  This
  1478. scheme uses B<Storable.pm> to perform the copy.
  1479.  
  1480. =back
  1481.  
  1482. =item keeproot => 1 (B<in+out>)
  1483.  
  1484. In its attempt to return a data structure free of superfluous detail and
  1485. unnecessary levels of indirection, C<XMLin()> normally discards the root
  1486. element name.  Setting the 'keeproot' option to '1' will cause the root element
  1487. name to be retained.  So after executing this code:
  1488.  
  1489.   $config = XMLin('<config tempdir="/tmp" />', keeproot => 1)
  1490.  
  1491. You'll be able to reference the tempdir as
  1492. C<$config-E<gt>{config}-E<gt>{tempdir}> instead of the default
  1493. C<$config-E<gt>{tempdir}>.
  1494.  
  1495. Similarly, setting the 'keeproot' option to '1' will tell C<XMLout()> that the
  1496. data structure already contains a root element name and it is not necessary to
  1497. add another.
  1498.  
  1499. =item rootname => 'string' (B<out>)
  1500.  
  1501. By default, when C<XMLout()> generates XML, the root element will be named
  1502. 'opt'.  This option allows you to specify an alternative name.
  1503.  
  1504. Specifying either undef or the empty string for the rootname option will
  1505. produce XML with no root elements.  In most cases the resulting XML fragment
  1506. will not be 'well formed' and therefore could not be read back in by C<XMLin()>.
  1507. Nevertheless, the option has been found to be useful in certain circumstances.
  1508.  
  1509. =item forcecontent (B<in>)
  1510.  
  1511. When C<XMLin()> parses elements which have text content as well as attributes,
  1512. the text content must be represented as a hash value rather than a simple
  1513. scalar.  This option allows you to force text content to always parse to
  1514. a hash value even when there are no attributes.  So for example:
  1515.  
  1516.   XMLin('<opt><x>text1</x><y a="2">text2</y></opt>', forcecontent => 1)
  1517.  
  1518. will parse to:
  1519.  
  1520.   {
  1521.     'x' => {           'content' => 'text1' },
  1522.     'y' => { 'a' => 2, 'content' => 'text2' }
  1523.   }
  1524.  
  1525. instead of:
  1526.  
  1527.   {
  1528.     'x' => 'text1',
  1529.     'y' => { 'a' => 2, 'content' => 'text2' }
  1530.   }
  1531.  
  1532. =item contentkey => 'keyname' (B<in+out>)
  1533.  
  1534. When text content is parsed to a hash value, this option let's you specify a
  1535. name for the hash key to override the default 'content'.  So for example:
  1536.  
  1537.   XMLin('<opt one="1">Text</opt>', contentkey => 'text')
  1538.  
  1539. will parse to:
  1540.  
  1541.   { 'one' => 1, 'text' => 'Text' }
  1542.  
  1543. instead of:
  1544.  
  1545.   { 'one' => 1, 'content' => 'Text' }
  1546.  
  1547. C<XMLout()> will also honour the value of this option when converting a hashref
  1548. to XML.
  1549.  
  1550. =item xmldecl => 1  or  xmldecl => 'string'  (B<out>)
  1551.  
  1552. If you want the output from C<XMLout()> to start with the optional XML
  1553. declaration, simply set the option to '1'.  The default XML declaration is:
  1554.  
  1555.         <?xml version='1.0' standalone='yes'?>
  1556.  
  1557. If you want some other string (for example to declare an encoding value), set
  1558. the value of this option to the complete string you require.
  1559.  
  1560. =item outputfile => <file specifier> (B<out>)
  1561.  
  1562. The default behaviour of C<XMLout()> is to return the XML as a string.  If you
  1563. wish to write the XML to a file, simply supply the filename using the
  1564. 'outputfile' option.  Alternatively, you can supply an IO handle object instead
  1565. of a filename.
  1566.  
  1567. =item noescape => 1 (B<out>)
  1568.  
  1569. By default, C<XMLout()> will translate the characters 'E<lt>', 'E<gt>', '&' and
  1570. '"' to '<', '>', '&' and '"' respectively.  Use this option to
  1571. suppress escaping (presumably because you've already escaped the data in some
  1572. more sophisticated manner).
  1573.  
  1574. =item parseropts => [ XML::Parser Options ] (B<in>)
  1575.  
  1576. Use this option to specify parameters that should be passed to the constructor
  1577. of the underlying XML::Parser object.  For example to turn on the namespace processing mode, you could say:
  1578.  
  1579.   XMLin($xml, parseropts => [ Namespaces => 1 ])
  1580.  
  1581. =back
  1582.  
  1583. =head1 OPTIONAL OO INTERFACE
  1584.  
  1585. The procedural interface is both simple and convenient however there are a
  1586. couple of reasons why you might prefer to use the object oriented (OO)
  1587. interface:
  1588.  
  1589. =over 4
  1590.  
  1591. =item *
  1592.  
  1593. to define a set of default values which should be used on all subsequent calls
  1594. to C<XMLin()> or C<XMLout()>
  1595.  
  1596. =item *
  1597.  
  1598. to override methods in B<XML::Simple> to provide customised behaviour
  1599.  
  1600. =back
  1601.  
  1602. The default values for the options described above are unlikely to suit
  1603. everyone.  The OO interface allows you to effectively override B<XML::Simple>'s
  1604. defaults with your preferred values.  It works like this:
  1605.  
  1606. First create an XML::Simple parser object with your preferred defaults:
  1607.  
  1608.   my $xs = new XML::Simple(forcearray => 1, keeproot => 1);
  1609.  
  1610. then call C<XMLin()> or C<XMLout()> as a method of that object:
  1611.  
  1612.   my $ref = $xs->XMLin($xml);
  1613.   my $xml = $xs->XMLout($ref);
  1614.  
  1615. You can also specify options when you make the method calls and these values
  1616. will be merged with the values specified when the object was created.  Values
  1617. specified in a method call take precedence.
  1618.  
  1619. Overriding methods is a more advanced topic but might be useful if for example
  1620. you wished to provide an alternative routine for escaping character data (the
  1621. escape_value method) or for building the initial parse tree (the build_tree
  1622. method).
  1623.  
  1624. =head1 ERROR HANDLING
  1625.  
  1626. The XML standard is very clear on the issue of non-compliant documents.  An
  1627. error in parsing any single element (for example a missing end tag) must cause
  1628. the whole document to be rejected.  B<XML::Simple> will die with an
  1629. appropriate message if it encounters a parsing error.
  1630.  
  1631. If dying is not appropriate for your application, you should arrange to call
  1632. C<XMLin()> in an eval block and look for errors in $@.  eg:
  1633.  
  1634.     my $config = eval { XMLin() };
  1635.     PopUpMessage($@) if($@);
  1636.  
  1637. Note, there is a common misconception that use of B<eval> will significantly
  1638. slow down a script.  While that may be true when the code being eval'd is in a
  1639. string, it is not true of code like the sample above.
  1640.  
  1641. =head1 EXAMPLES
  1642.  
  1643. When C<XMLin()> reads the following very simple piece of XML:
  1644.  
  1645.     <opt username="testuser" password="frodo"></opt>
  1646.  
  1647. it returns the following data structure:
  1648.  
  1649.     {
  1650.       'username' => 'testuser',
  1651.       'password' => 'frodo'
  1652.     }
  1653.  
  1654. The identical result could have been produced with this alternative XML:
  1655.  
  1656.     <opt username="testuser" password="frodo" />
  1657.  
  1658. Or this (although see 'forcearray' option for variations):
  1659.  
  1660.     <opt>
  1661.       <username>testuser</username>
  1662.       <password>frodo</password>
  1663.     </opt>
  1664.  
  1665. Repeated nested elements are represented as anonymous arrays:
  1666.  
  1667.     <opt>
  1668.       <person firstname="Joe" lastname="Smith">
  1669.         <email>joe@smith.com</email>
  1670.         <email>jsmith@yahoo.com</email>
  1671.       </person>
  1672.       <person firstname="Bob" lastname="Smith">
  1673.         <email>bob@smith.com</email>
  1674.       </person>
  1675.     </opt>
  1676.  
  1677.     {
  1678.       'person' => [
  1679.                     {
  1680.                       'email' => [
  1681.                                    'joe@smith.com',
  1682.                                    'jsmith@yahoo.com'
  1683.                                  ],
  1684.                       'firstname' => 'Joe',
  1685.                       'lastname' => 'Smith'
  1686.                     },
  1687.                     {
  1688.                       'email' => 'bob@smith.com',
  1689.                       'firstname' => 'Bob',
  1690.                       'lastname' => 'Smith'
  1691.                     }
  1692.                   ]
  1693.     }
  1694.  
  1695. Nested elements with a recognised key attribute are transformed (folded) from
  1696. an array into a hash keyed on the value of that attribute:
  1697.  
  1698.     <opt>
  1699.       <person key="jsmith" firstname="Joe" lastname="Smith" />
  1700.       <person key="tsmith" firstname="Tom" lastname="Smith" />
  1701.       <person key="jbloggs" firstname="Joe" lastname="Bloggs" />
  1702.     </opt>
  1703.  
  1704.     {
  1705.       'person' => {
  1706.                     'jbloggs' => {
  1707.                                    'firstname' => 'Joe',
  1708.                                    'lastname' => 'Bloggs'
  1709.                                  },
  1710.                     'tsmith' => {
  1711.                                   'firstname' => 'Tom',
  1712.                                   'lastname' => 'Smith'
  1713.                                 },
  1714.                     'jsmith' => {
  1715.                                   'firstname' => 'Joe',
  1716.                                   'lastname' => 'Smith'
  1717.                                 }
  1718.                   }
  1719.     }
  1720.  
  1721.  
  1722. The <anon> tag can be used to form anonymous arrays:
  1723.  
  1724.     <opt>
  1725.       <head><anon>Col 1</anon><anon>Col 2</anon><anon>Col 3</anon></head>
  1726.       <data><anon>R1C1</anon><anon>R1C2</anon><anon>R1C3</anon></data>
  1727.       <data><anon>R2C1</anon><anon>R2C2</anon><anon>R2C3</anon></data>
  1728.       <data><anon>R3C1</anon><anon>R3C2</anon><anon>R3C3</anon></data>
  1729.     </opt>
  1730.  
  1731.     {
  1732.       'head' => [
  1733.           [ 'Col 1', 'Col 2', 'Col 3' ]
  1734.         ],
  1735.       'data' => [
  1736.           [ 'R1C1', 'R1C2', 'R1C3' ],
  1737.           [ 'R2C1', 'R2C2', 'R2C3' ],
  1738.           [ 'R3C1', 'R3C2', 'R3C3' ]
  1739.         ]
  1740.     }
  1741.  
  1742. Anonymous arrays can be nested to arbirtrary levels and as a special case, if
  1743. the surrounding tags for an XML document contain only an anonymous array the
  1744. arrayref will be returned directly rather than the usual hashref:
  1745.  
  1746.     <opt>
  1747.       <anon><anon>Col 1</anon><anon>Col 2</anon></anon>
  1748.       <anon><anon>R1C1</anon><anon>R1C2</anon></anon>
  1749.       <anon><anon>R2C1</anon><anon>R2C2</anon></anon>
  1750.     </opt>
  1751.  
  1752.     [
  1753.       [ 'Col 1', 'Col 2' ],
  1754.       [ 'R1C1', 'R1C2' ],
  1755.       [ 'R2C1', 'R2C2' ]
  1756.     ]
  1757.  
  1758. Elements which only contain text content will simply be represented as a
  1759. scalar.  Where an element has both attributes and text content, the element
  1760. will be represented as a hashref with the text content in the 'content' key:
  1761.  
  1762.   <opt>
  1763.     <one>first</one>
  1764.     <two attr="value">second</two>
  1765.   </opt>
  1766.  
  1767.   {
  1768.     'one' => 'first',
  1769.     'two' => { 'attr' => 'value', 'content' => 'second' }
  1770.   }
  1771.  
  1772. Mixed content (elements which contain both text content and nested elements)
  1773. will be not be represented in a useful way - element order and significant
  1774. whitespace will be lost.  If you need to work with mixed content, then
  1775. XML::Simple is not the right tool for your job - check out the next section.
  1776.  
  1777. =head1 WHERE TO FROM HERE?
  1778.  
  1779. B<XML::Simple> is by nature very simple.  
  1780.  
  1781. =over 4
  1782.  
  1783. =item *
  1784.  
  1785. The parsing process liberally disposes of 'surplus' whitespace - some 
  1786. applications will be sensitive to this.
  1787.  
  1788. =item *
  1789.  
  1790. Slurping data into a hash will implicitly discard information about attribute
  1791. order.  Normally this would not be a problem because any items for which order
  1792. is important would typically be encoded as elements rather than attributes.
  1793. However B<XML::Simple>'s aggressive slurping and folding algorithms can
  1794. defeat even these techniques.
  1795.  
  1796. =item *
  1797.  
  1798. The API offers little control over the output of C<XMLout()>.  In particular,
  1799. it is not especially likely that feeding the output from C<XMLin()> into
  1800. C<XMLout()> will reproduce the original XML (although passing the output from
  1801. C<XMLout()> into C<XMLin()> should reproduce the original data structure).
  1802.  
  1803. =item *
  1804.  
  1805. C<XMLout()> cannot produce well formed HTML unless you feed it with care - hash
  1806. keys must conform to XML element naming rules and undefined values should be
  1807. avoided.
  1808.  
  1809. =item *
  1810.  
  1811. C<XMLout()> does not currently support encodings (although it shouldn't stand
  1812. in your way if you feed it encoded data).
  1813.  
  1814. =item *
  1815.  
  1816. If you're attempting to get the output from C<XMLout()> to conform to a
  1817. specific DTD, you're almost certainly using the wrong tool for the job.
  1818.  
  1819. =back
  1820.  
  1821. If any of these points are a problem for you, then B<XML::Simple> is probably
  1822. not the right module for your application.  The following section is intended
  1823. to give pointers which might help you select a more powerful tool - it's a bit
  1824. sketchy right now but submissions are welcome.
  1825.  
  1826. =over 4
  1827.  
  1828. =item XML::Parser
  1829.  
  1830. B<XML::Simple> is built on top of B<XML::Parser>, so if you have B<XML::Simple>
  1831. working you already have B<XML::Parser> installed.  This is a comprehensive,
  1832. fast, industrial strength (non-validating) parsing tool built on top of James
  1833. Clark's 'expat' library.  It does support converting XML into a Perl tree
  1834. structure (with full support for mixed content) but for arbritrarily large
  1835. documents you're probably better off defining handler routines for
  1836. B<XML::Parser> to call as each element is parsed.  The distribution includes a
  1837. number of sample applications.
  1838.  
  1839. =item XML::DOM
  1840.  
  1841. The data structure returned by B<XML::Simple> was designed for convenience
  1842. rather than standards compliance.  B<XML::DOM> is a parser built on top of
  1843. B<XML::Parser>, which returns a 'Document' object conforming to the API of the
  1844. Document Object Model as described at http://www.w3.org/TR/REC-DOM-Level-1 .
  1845. This Document object can then be examined, modified and written back out to a
  1846. file or converted to a string. 
  1847.  
  1848. =item XML::Grove
  1849.  
  1850. Compliance with the Document Object Model might be particularly useful when
  1851. porting code to or from another language.  However, if you're looking for a
  1852. simpler, 'perlish' object interface, take a look at B<XML::Grove>.
  1853.  
  1854. =item XML::Twig
  1855.  
  1856. XML::Twig offers a tree-oriented interface to a document while still allowing
  1857. the processing of documents of any size. It allows processing chunks of
  1858. documents in tree-mode which can then be flushed or purged from the memory.
  1859. The XML::Twig page is at http://standards.ieee.org/resources/spasystem/twig/
  1860.  
  1861. =item libxml-perl
  1862.  
  1863. B<libxml-perl> is a collection of Perl modules, scripts, and documents for
  1864. working with XML in Perl. The distribution includes PerlSAX - a Perl
  1865. implementation of the SAX API.  It also include B<XML::PatAct> modules for
  1866. processing XML by defining patterns and associating them with actions.  For more
  1867. details see http://bitsko.slc.ut.us/libxml-perl/ .
  1868.  
  1869. =item XML::PYX
  1870.  
  1871. B<XML::PYX> allows you to apply Unix command pipelines (using grep, sed etc) to
  1872. filter or transform XML files.  Ideally suited for tasks such as extracting all
  1873. text content or stripping out all occurrences of a particular tag without
  1874. having to write a Perl script at all.  It can also be used for transforming
  1875. HTML to XHTML.
  1876.  
  1877. =item XML::RAX
  1878.  
  1879. If you wish to process XML files containing a series of 'records', B<XML::RAX>
  1880. provides a simple purpose-designed interface.  If it still hasn't made it to
  1881. CPAN, try: http://www.dancentury.com/robh/
  1882.  
  1883. =item XML::Writer
  1884.  
  1885. B<XML::Writer> is a helper module for Perl programs that write XML documents.
  1886.  
  1887. =item XML::Dumper
  1888.  
  1889. B<XML::Dumper> dumps Perl data to a structured XML format. B<XML::Dumper> can
  1890. also read XML data that was previously dumped by the module and convert it back
  1891. to Perl. 
  1892.  
  1893. =back
  1894.  
  1895. Don't forget to check out the Perl XML FAQ at:
  1896. http://www.perlxml.com/faq/perl-xml-faq.html
  1897.  
  1898.  
  1899. =head1 STATUS
  1900.  
  1901. This version (1.06) is the current stable version.  
  1902.  
  1903. =head1 SEE ALSO
  1904.  
  1905. B<XML::Simple> requires B<XML::Parser> and B<File::Spec>.  The optional caching
  1906. functions require B<Storable>.
  1907.  
  1908. =head1 COPYRIGHT 
  1909.  
  1910. Copyright 1999-2001 Grant McLean E<lt>grantm@cpan.orgE<gt>
  1911.  
  1912. This library is free software; you can redistribute it and/or modify it
  1913. under the same terms as Perl itself. 
  1914.  
  1915. =cut
  1916.  
  1917.  
  1918.